-
Notifications
You must be signed in to change notification settings - Fork 412
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enable dune cache by default #10710
Enable dune cache by default #10710
Conversation
73ad59c
to
bba74ca
Compare
Before this default is flipped, we need to have a story for how this interact with user rules. As a first approximation, all user rules are unsafe to cache this way. So users should be able to opt-in to enable caching for their own rules. |
FMU, as this PR is only changing the default, if the user has a configuration, it will take it instead of the default. Or am I missing something? 😕 |
The problem lies in that most users do not have such a configuration. Moreover, most project contain user rules of the form:
That are absolutely not safe to cache. Therefore, flipping the default like is done in this PR is highly likely to cause a lot of unintended breakage. |
Incorporated (very helpful) comments by Rudi on #10789, we now have a different environment variable named (for now) DUNE_CACHE_USER_RULES defaulting to false, the old DUNE_CACHE is now on by default, and |
The intended behaviour is now, as far as I understand correctly (Writing mostly for my future self here) :
|
I don't think so. Since disabling the cache will only affect the package management rules which aren't stable. |
I think I am misunderstanding something because as we see in the tests, a lot of them fail if |
@rgrinberg can you remind me why user rules are not safe to cache? |
5583939
to
df9980d
Compare
From experience, I can say that many rules do not specify their dependencies correctly. Some rules aren't even deterministic. These kinds of rules can poison the cache without an easy way to diagnose the issues. |
eb84f6d
to
256fdd8
Compare
I don't think the Nix failures have anything to do with the PR. I'll add the overrides for rules from package management in a second PR so this is just laying down the groundwork for it. |
As mentioned on slack, the error is relevant. Dune is trying to create the cache directory at $HOME and nix is rightfully forbidding that. |
One way to work around this would be to disable the cache if the cache dir isn't writeable. Maybe just emit a warning? |
@rgrinberg I've added some code that detects if the directories can't be created, it disables the cache and warns. I had to add a case to |
Setting env vars across different build setups can be pretty time-consuming and often not trivial. I agree with @samoht that this is a regression for users. |
I also agree that this is a regression. I hope "set some new environment variable and move on" is not a typical experience when upgrading to a new version of Dune. We should find a better way! |
We tried to find a better way but this is all we could come up with. The cache has to be enabled for package management, but doing so while opting in to cache all user rules would be even more disruptive. At least this way the disruption is limited to the small subset of users using the cache. Suggestions are welcome. |
Well, package management is a new feature, and it seems fair to require early adopters to, say, set |
In general, penalising rules that do the right thing seems surprising. Surely, the incentives should go the other way around. |
This suggestion is with conjunction to enabling the dune cache by default? It might be worth recalling why we never enabled the cache by default in the first place. Our own OCaml rules had some correctness issues we never got to the bottom of (around C compilation and linking IIRC). User rules were in an even worse spot. Those were mostly unsandboxed and thus often broken. I don't think the situation has changed much since. I don't want to punish users that write correct rules, but I also know it would be way too optimistic to assume such rules are correct by default either. People who enabled the cache are a minority of advanced users, so I think putting the burden of maintaining config on them is more fair than on the users of package management. Some of those are going to be beginners that are just getting started with dune. |
I've been using dune-cache extensively for years now. The subset of the ecosystem I am working with does not seem to have any broken rules. So I'm surprised that you are so conservative here (even if I understand the rationale, I'm not sure I agree with the proposed workaround). In any case, I would much rather edit |
Another thing to consider is what will happen to IIANM it uses the cache, so it would require adaptation? Indeed there is large use of dune cache (and it is often why Coq people migrate from make to dune, to have a cache), so IMHO the user experience of this change could be not super good, if that silently stops working. There is now a changelog entry proposed tho. Maybe a good compromise would be to lead towards a setup more friendly to the "status quo" of users, we could have a setup such that:
Dune package management could emit a warning if users are running with WDYT folks? |
I appreciate all the discussion going on here, hearing differing viewpoints is always nice. I think I am convinced by your arguments @ejgallego & @samoht. My idea of what to do next would be almost the same as what was proposed above :
|
Sounds great to me @ElectreAAS ; maybe we could actually deprecate This can be done properly using I like the idea of using |
I'm lukewarm about it. I think having the cache enabled or disabled vs selecting which rules are cacheable are orthogonal things and mixing them up in a single config will lead to confusion and lost flexibility down the road. On the other hand, if it really is so difficult to move to a different way to enable the cache for the coq devs (how did you get them on all on board to use the cache in the first place?), then so be it. |
That is a very interesting observation. Indeed I assumed the opposite, that enabling the cache and understanding what gets cached were very related concepts. My thought process is like this: imagine I do We could indeed split the config in something like What would an example of "confusion" or "lost flexibility" in the scenario look like?
I am not so worried about the Coq devs, that's a small set of users, but more about a lot of users (mainly "industrial") that rely on the cache. In general, this is a de facto breaking change and may require significant fiddling with things like the github ocaml action etc...
I am not sure I understand the question, I guess once they saw it in action most enabled it, a full Coq compilation is very expensive, so caching pays off immensely. |
Why not proceed as follows:
Then this PR should amount to changing the default to |
That's the situation today, but I think we can start marking some rules as safe to cache gradually. I'm thinking ocamldep rules, user rules that are sandboxed, some of the compilation rules.
Here's the main difference: when you mark a rule as unsafe for caching, this bit ends up being included in the action digest. The consequence of doing this is that once this bit is flipped (via the environment variable for example), the action will re-run and the cache entry will be populated (or possibly trimmed if going the other way). On the other hand, enabling/disabling the cache has no effect on the rules themselves. So it can never trigger recompilation. Maybe this distinction isn't particularly important or the two types of settings can be unified somehow in the future? As I said, we can go along with your suggestion if this will make transitioning easier for you. It's good enough for us to proceed on the package management side.
My point is that you somehow told the team that a config file needs to be updated to enable the cache. Well, you can tell them that a new config is needed in the same way. Or, if you have some makefile you all share, you can just set the config there. |
@rgrinberg what do you think of the concrete proposal above ? It would provide the same effect as in this PR while remaining fully backwards compatible, as far as I can see. |
It sounds quite similar to Emilio's proposal. Seems fine as well. |
See #10944 |
Indeed, this is why I was requesting for some setting in In the Coq world there a multitude of different CI / testing deployements, and not only Coq devs, but many other users would be affected by this change. Unfortunately there is nothing close to a homogeneous Coq build CI setup (we are trying to improve that, check your mail if you are interested ;)), but indeed I don't know how to write a guide on adding a new env var effectively, there are just too many combinations of shells and dev setups, it seems to me. The config file is nicer to implement I feel. A bit orthogonal to this is the topic of backwards compat, IMO dune has been doing superb on this aspect, so changes like this are better controlled by I am often bitten by rules that are cached wrongly, so indeed it is great to progress on this front, so we get better tools to debug and mark bad rules. |
Another thing that you might find worth doing is to mark all the coq rules as being explicitly safe. If you're confident about those, might as well enable them under |
Indeed thanks! I've added this to the list of TODOs to the One reason we didn't mark them as safe, is that while Coq rules are "cache safe", they are not "sandbox" safe, due to the "hack" of including hashes of deps in .vo files. We tried sandboxing the Coq rules, and they were way slower, on the other hand we'd love to have a flag to do that so we can do "sandbox but slow" and "not sandbox but fast". Of course, it'd be even better to make sandboxing faster, but in this case it is a bit hard due to the number of egdes added to the build graph in Coq sandboxed mode. This is added to the working group TODO, will come back to the topic when we discuss what to do. |
* Added feature flag to enable dune cache by default
CHANGES: ### Fixed - Show the context name for errors happening in non-default contexts. (ocaml/dune#10414, fixes ocaml/dune#10378, @jchavarri) - Correctly declare dependencies of indexes so that they are rebuilt when needed. (ocaml/dune#10623, @voodoos) - Don't depend on coq-stdlib being installed when expanding variables of the `coq.version` family (ocaml/dune#10631, fixes ocaml/dune#10629, @gares) - Error out if no files are found when using `copy_files`. (ocaml/dune#10649, @jchavarri) - Re_export dune-section private library in the dune-site library stanza, in order to avoid failure when generating and building sites modules with implicit_transitive_deps = false. (ocaml/dune#10650, fixes ocaml/dune#9661, @MA0100) - Expect test fixes: support multiple modes and fix dependencies when there is a custom runner (ocaml/dune#10671, @vouillon) - In a `(library)` stanza with `(extra_objects)` and `(foreign_stubs)`, avoid double linking the extra object files in the final executable. (ocaml/dune#10783, fixes ocaml/dune#10785, @nojb) - Map `(re_export)` library dependencies to the `exports` field in `META` files, and vice-versa. This field was proposed in to https://discuss.ocaml.org/t/proposal-a-new-exports-field-in-findlib-meta-files/13947. The field is included in Dune-generated `META` files only when the Dune lang version is >= 3.17. (ocaml/dune#10831, fixes ocaml/dune#10830, @nojb) - Fix staged pps preprocessors on Windows (which were not working at all previously) (ocaml/dune#10869, fixes ocaml/dune#10867, @nojb) - Fix `dune describe` when an executable is disabled with `enabled_if`. (ocaml/dune#10881, fixes ocaml/dune#10779, @moyodiallo) - Fix an issue where C stubs would be rebuilt whenever the stderr of Dune was redirected. (ocaml/dune#10883, fixes ocaml/dune#10882, @nojb) - Format long lists in s-expressions to fill the line instead of formatting them in a vertical way (ocaml/dune#10892, fixes ocaml/dune#10860, @nojb) - Fix the URL opened by the command `dune ocaml doc`. (ocaml/dune#10897, @gridbugs) - Fix the file referred to in the error/warning message displayed due to the dune configuration version not supporting a particular configuration stanza in use. (ocaml/dune#10923, @H-ANSEN) - Fix `enabled_if` when it uses `env` variable. (ocaml/dune#10936, fixes ocaml/dune#10905, @moyodiallo) - Fix exec -w for relative paths with --root argument (ocaml/dune#10982, @gridbugs) - Do not ignore the `(locks ..)` field in the `test` and `tests` stanza (ocaml/dune#11081, @rgrinberg) - Tolerate files without extension when generating merlin rules. (ocaml/dune#11128, @anmonteiro) ### Added - Make Merlin/OCaml-LSP aware of "hidden" dependencies used by `(implicit_transitive_deps false)` via the `-H` compiler flag. (ocaml/dune#10535, @voodoos) - Add support for the -H flag (introduced in OCaml compiler 5.2) in dune (requires lang versions 3.17). This adaptation gives the correct semantics for `(implicit_transitive_deps false)`. (ocaml/dune#10644, fixes ocaml/dune#9333, ocsigen/tyxml#274, ocaml/dune#2733, ocaml/dune#4963, @MA0100) - Add support for specifying Gitlab organization repositories in `source` stanzas (ocaml/dune#10766, fixes ocaml/dune#6723, @H-ANSEN) - New option to control jsoo sourcemap generation in env and executable stanza (ocaml/dune#10777, fixes ocaml/dune#10673, @hhugo) - One can now control jsoo compilation_mode inside an executable stanza (ocaml/dune#10777, fixes ocaml/dune#10673, @hhugo) - Add support for specifying default values of the `authors`, `maintainers`, and `license` stanzas of the `dune-project` file via the dune config file. Default values are set using the `(project_defaults)` stanza (ocaml/dune#10835, @H-ANSEN) - Add names to source tree events in performance traces (ocaml/dune#10884, @jchavarri) - Add `codeberg` as an option for defining project sources in dune-project files. For example, `(source (codeberg user/repo))`. (ocaml/dune#10904, @nlordell) - `dune runtest` can now run individual tests with `dune runtest mytest.t` (ocaml/dune#11041, @Alizter). - Wasm_of_ocaml support (ocaml/dune#11093, @vouillon) - Add a `coqdep_flags` field to the `coq` field of the `env` stanza, and to the `coq.theory` stanza, allowing to configure `coqdep` flags. (ocaml/dune#11094, @rlepigre) ### Changed - Remove all remnants of the experimental `patch-back-source-tree`. (ocaml/dune#10771, @rgrinberg) - Change the preset value for author and maintainer fields in the `dune-project` file to encourage including emails. (ocaml/dune#10848, @punchagan) - Tweak the preset value for tags in the `dune-project` file to hint at topics not having a special meaning. (ocaml/dune#10849, @punchagan) - Change some colors to improve readability in light-mode terminals (ocaml/dune#10890, @gridbugs) - Forward the linkall flag to jsoo in whole program compilation as well (ocaml/dune#10935, @hhugo) - Configurator uses `pkgconf` as pkg-config implementation when available and forwards it the `target` of `ocamlc -config`. (ocaml/dune#10937, @pirbo) - Enable Dune cache by default. Add a new Dune cache setting `enabled-except-user-rules`, which enables the Dune cache, but excludes user-written rules from it. This is a conservative choice that can avoid breaking rules whose dependencies are not correctly specified. This is the current default. (ocaml/dune#10944, ocaml/dune#10710, @nojb, @ElectreAAS) - Do not add `dune` dependency in `dune-project` when creating projects with `dune init proj`. The Dune dependency is implicitely added when generating opam files (ocaml/dune#11129, @Leonidas-from-XIV)
CHANGES: ### Fixed - Show the context name for errors happening in non-default contexts. (ocaml/dune#10414, fixes ocaml/dune#10378, @jchavarri) - Correctly declare dependencies of indexes so that they are rebuilt when needed. (ocaml/dune#10623, @voodoos) - Don't depend on coq-stdlib being installed when expanding variables of the `coq.version` family (ocaml/dune#10631, fixes ocaml/dune#10629, @gares) - Error out if no files are found when using `copy_files`. (ocaml/dune#10649, @jchavarri) - Re_export dune-section private library in the dune-site library stanza, in order to avoid failure when generating and building sites modules with implicit_transitive_deps = false. (ocaml/dune#10650, fixes ocaml/dune#9661, @MA0100) - Expect test fixes: support multiple modes and fix dependencies when there is a custom runner (ocaml/dune#10671, @vouillon) - In a `(library)` stanza with `(extra_objects)` and `(foreign_stubs)`, avoid double linking the extra object files in the final executable. (ocaml/dune#10783, fixes ocaml/dune#10785, @nojb) - Map `(re_export)` library dependencies to the `exports` field in `META` files, and vice-versa. This field was proposed in to https://discuss.ocaml.org/t/proposal-a-new-exports-field-in-findlib-meta-files/13947. The field is included in Dune-generated `META` files only when the Dune lang version is >= 3.17. (ocaml/dune#10831, fixes ocaml/dune#10830, @nojb) - Fix staged pps preprocessors on Windows (which were not working at all previously) (ocaml/dune#10869, fixes ocaml/dune#10867, @nojb) - Fix `dune describe` when an executable is disabled with `enabled_if`. (ocaml/dune#10881, fixes ocaml/dune#10779, @moyodiallo) - Fix an issue where C stubs would be rebuilt whenever the stderr of Dune was redirected. (ocaml/dune#10883, fixes ocaml/dune#10882, @nojb) - Fix the URL opened by the command `dune ocaml doc`. (ocaml/dune#10897, @gridbugs) - Fix the file referred to in the error/warning message displayed due to the dune configuration version not supporting a particular configuration stanza in use. (ocaml/dune#10923, @H-ANSEN) - Fix `enabled_if` when it uses `env` variable. (ocaml/dune#10936, fixes ocaml/dune#10905, @moyodiallo) - Fix exec -w for relative paths with --root argument (ocaml/dune#10982, @gridbugs) - Do not ignore the `(locks ..)` field in the `test` and `tests` stanza (ocaml/dune#11081, @rgrinberg) - Tolerate files without extension when generating merlin rules. (ocaml/dune#11128, @anmonteiro) ### Added - Make Merlin/OCaml-LSP aware of "hidden" dependencies used by `(implicit_transitive_deps false)` via the `-H` compiler flag. (ocaml/dune#10535, @voodoos) - Add support for the -H flag (introduced in OCaml compiler 5.2) in dune (requires lang versions 3.17). This adaptation gives the correct semantics for `(implicit_transitive_deps false)`. (ocaml/dune#10644, fixes ocaml/dune#9333, ocsigen/tyxml#274, ocaml/dune#2733, ocaml/dune#4963, @MA0100) - Add support for specifying Gitlab organization repositories in `source` stanzas (ocaml/dune#10766, fixes ocaml/dune#6723, @H-ANSEN) - New option to control jsoo sourcemap generation in env and executable stanza (ocaml/dune#10777, fixes ocaml/dune#10673, @hhugo) - One can now control jsoo compilation_mode inside an executable stanza (ocaml/dune#10777, fixes ocaml/dune#10673, @hhugo) - Add support for specifying default values of the `authors`, `maintainers`, and `license` stanzas of the `dune-project` file via the dune config file. Default values are set using the `(project_defaults)` stanza (ocaml/dune#10835, @H-ANSEN) - Add names to source tree events in performance traces (ocaml/dune#10884, @jchavarri) - Add `codeberg` as an option for defining project sources in dune-project files. For example, `(source (codeberg user/repo))`. (ocaml/dune#10904, @nlordell) - `dune runtest` can now run individual tests with `dune runtest mytest.t` (ocaml/dune#11041, @Alizter). - Wasm_of_ocaml support (ocaml/dune#11093, @vouillon) - Add a `coqdep_flags` field to the `coq` field of the `env` stanza, and to the `coq.theory` stanza, allowing to configure `coqdep` flags. (ocaml/dune#11094, @rlepigre) ### Changed - Remove all remnants of the experimental `patch-back-source-tree`. (ocaml/dune#10771, @rgrinberg) - Change the preset value for author and maintainer fields in the `dune-project` file to encourage including emails. (ocaml/dune#10848, @punchagan) - Tweak the preset value for tags in the `dune-project` file to hint at topics not having a special meaning. (ocaml/dune#10849, @punchagan) - Change some colors to improve readability in light-mode terminals (ocaml/dune#10890, @gridbugs) - Forward the linkall flag to jsoo in whole program compilation as well (ocaml/dune#10935, @hhugo) - Configurator uses `pkgconf` as pkg-config implementation when available and forwards it the `target` of `ocamlc -config`. (ocaml/dune#10937, @pirbo) - Enable Dune cache by default. Add a new Dune cache setting `enabled-except-user-rules`, which enables the Dune cache, but excludes user-written rules from it. This is a conservative choice that can avoid breaking rules whose dependencies are not correctly specified. This is the current default. (ocaml/dune#10944, ocaml/dune#10710, @nojb, @ElectreAAS) - Do not add `dune` dependency in `dune-project` when creating projects with `dune init proj`. The Dune dependency is implicitely added when generating opam files (ocaml/dune#11129, @Leonidas-from-XIV)
This PR enables the dune cache by default, without having to use
DUNE_CACHE=enabled
. The idea is to lay a groundwork to enable caching of actions that are safe to cache and have them be cached out of the box in the future.To do so the default of whether actions can be cached is moved a new
Clflag
(Clfags.can_go_into_shared_cache_default
). This value is set tofalse
as most actions can't be cached, thus it could break code to enable caching of them by default. This flag can be overridden via theDUNE_CACHE_RULES=enabled
environment variable/toggle, which will then allow to cache all actions (as it did before when you enabledDUNE_CACHE=enabled
).Some adjustments for the creation of the cache directories needed to be made if Dune is run in environments where the cache directory cannot be written (e.g. when packaging for Nix or Debian), it will output a warning in such case and continue with the cache disabled as before. The warning can be silenced by specifically setting
DUNE_CACHE=disabled
.The tests that require the rules to be cached have been updated to include
DUNE_CACHE_RULES=enabled
and exhibit the same behavior wrt. caching, hashes and trimming as before.In a future PR, some of the actions to that are deemed to be safe for caching (e.g. downloading package sources) will have their default value set as such.